package com.dynamic.idea.quick.develop.plugin.dialog.child;

import cn.hutool.core.bean.BeanUtil;
import com.dynamic.idea.quick.develop.plugin.entity.base02.model.ImportStruct;
import com.dynamic.idea.quick.develop.plugin.entity.base02.model.RequestParamStruct;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.ComponentValidator;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.ui.ValidationInfo;
import com.intellij.openapi.ui.panel.ComponentPanelBuilder;
import com.intellij.openapi.ui.panel.PanelGridBuilder;
import com.intellij.psi.PsiClass;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.search.PsiShortNamesCache;
import com.intellij.ui.SingleSelectionModel;
import com.intellij.ui.*;
import com.intellij.ui.components.JBList;
import com.intellij.ui.components.JBTextField;
import com.intellij.ui.components.fields.ExpandableTextField;
import com.intellij.util.ui.JBUI;
import com.intellij.util.ui.UI;
import com.intellij.util.ui.UIUtil;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import javax.swing.*;
import javax.swing.event.DocumentEvent;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import java.util.*;
import java.util.function.Supplier;

/**
 * 请求参数对话框
 */
public class RequestParameterDialogWrapper extends DialogWrapper {

    private Project project;

    /** 请求参数 */
    private RequestParamStruct requestParamStruct=null;

    // 包名 不显示在界面上
//    private String packageName=null;

    // 类名 不显示在界面上
//    private String className=null;

    // 泛型的包名1
//    private String genericsPackageName1=null;
    // 泛型的包名1
//    private String  genericsClassName1=null;

    // 现在的请求参数
     private RequestParamStruct nowRequestParamStruct=null;

    // 参数文本域
    private JTextField parameterJTextField=null;

    // 注释文本域
    private JTextField commentJTextField=null;

    // 请求参数列表数据
    private Map<String,RequestParamStruct> requestParamName2StructDataMap=null;
    // 预览的全部包名文本域
    private ExpandableTextField previewAllJTextField=null;

    // 预览的简单包名文本域
    private ExpandableTextField previewSimpleJTextField=null;



    /**
     * 类型:Add(添加)或 Edit(编辑)
     */
    private String type;

    public RequestParameterDialogWrapper(@Nullable Project project,String type,Map<String,RequestParamStruct> requestParamName2StructDataMap,RequestParamStruct requestParamStruct) {
        super(true);
        this.project=project;
        this.requestParamName2StructDataMap=requestParamName2StructDataMap;
        this.type=type;
        if (StringUtils.equalsIgnoreCase("add",type)){
            setTitle("Add Parameter");
        }else if (StringUtils.equalsIgnoreCase("edit",type)){
            setTitle("Edit Parameter");
        }else if (StringUtils.equalsIgnoreCase("returnEdit",type)){
            setTitle("Return");
        }
        this.requestParamStruct=requestParamStruct;
        init();
    }


    @Nullable
    @Override
    protected JComponent createCenterPanel() {

        // 设置确定按钮不可点击
        if (!StringUtils.equalsIgnoreCase("returnEdit",type)){
            getOKAction().setEnabled(false);
        }

        nowRequestParamStruct=new RequestParamStruct();

        // 包名
        previewAllJTextField=new ExpandableTextField();
        //包名 不可修改
//        packageJTextField.setEditable(false);

        // 类名
        previewSimpleJTextField=new ExpandableTextField();

        // 类名 不可修改
//        classJTextField.setEditable(false);

        // 参数名
        parameterJTextField=new JBTextField();

        // 注释文本域
        commentJTextField=new JBTextField();

        parameterJTextField.getDocument().addDocumentListener(new DocumentAdapter() {
            @Override
            protected void textChanged(@NotNull DocumentEvent e) {
//                System.out.println(parameterJTextField.getText());
                String parameter = StringUtils.trimToEmpty(parameterJTextField.getText());

                nowRequestParamStruct.setParamName(parameter);
                showData();
//                parameterJTextField.setText(parameter);

               /* String className=nowRequestParamStruct.getClassName();

                String packageName=nowRequestParamStruct.getPackageName();

                String simpleShowParameter ="";
                if (StringUtils.isBlank(parameter)){
                    simpleShowParameter = className;
                }else {
                    simpleShowParameter = className + " " + parameter;
                }

                String allShowParameter=packageName+"."+simpleShowParameter;
                previewAllJTextField.setText(allShowParameter);
                previewSimpleJTextField.setText(simpleShowParameter);*/
            }
        });

        // 校验参数名是否非空
        if (!StringUtils.equalsIgnoreCase("returnEdit",type)){
            validatorJTextFiled(parameterJTextField,"parameter");
        }

        if (requestParamStruct!=null&&(StringUtils.equalsIgnoreCase(type,"edit")||StringUtils.equalsIgnoreCase(type,"returnEdit"))){
            String parameter = StringUtils.trimToEmpty(requestParamStruct.getParamName());
            parameterJTextField.setText(parameter);

            if (StringUtils.isNotBlank(requestParamStruct.getComment())){
                commentJTextField.setText(StringUtils.trimToNull(requestParamStruct.getComment()));
            }
            previewAllJTextField.setText(requestParamStruct.showQualifiedNameParam());
            previewSimpleJTextField.setText(requestParamStruct.showSimpleNameParam());

            BeanUtil.copyProperties(requestParamStruct,nowRequestParamStruct);
        }

        // java类
//        JavaPsiFacade javaPsiFacade = JavaPsiFacade.getInstance(project);

        // 全局搜索
//        GlobalSearchScope allSearchScope=GlobalSearchScope.allScope(project);
        //搜索参数文本框
        SearchTextField searchTextField=new SearchTextField();
        //搜索参数展示列表
        ComponentPanelBuilder searchShowComponentPanelBuilder = searchParameterTextResponse(searchTextField);

        // 泛型搜索框1
        SearchTextField genericsSearchTextField=new SearchTextField();

        ComponentPanelBuilder genericsSearchShowComponentPanelBuilder = genericsSearchParameterTextResponse(genericsSearchTextField,0);

        // 泛型搜索框2
        SearchTextField genericsSearchTextField2=new SearchTextField();
        ComponentPanelBuilder genericsSearchShowComponentPanelBuilder2 = genericsSearchParameterTextResponse(genericsSearchTextField2,1);

        PanelGridBuilder panelGridBuilder = UI.PanelFactory.grid().
                add(UI.PanelFactory.panel(searchTextField).withLabel("search:")).
                add(searchShowComponentPanelBuilder);
//                add(UI.PanelFactory.panel(parameterJTextField).withLabel("parameter"));
        if (!StringUtils.equalsIgnoreCase("returnEdit",type)){
            panelGridBuilder.add(UI.PanelFactory.panel(parameterJTextField).withLabel("parameter"));
        }
        JPanel p = panelGridBuilder.add(UI.PanelFactory.panel(commentJTextField).withLabel("comment")).
                add(UI.PanelFactory.panel(genericsSearchTextField).withLabel("generics1:")).
                add(genericsSearchShowComponentPanelBuilder).

                add(UI.PanelFactory.panel(genericsSearchTextField2).withLabel("generics2:")).
                add(genericsSearchShowComponentPanelBuilder2).

                add(UI.PanelFactory.panel(previewSimpleJTextField).withLabel("simple")).
                add(UI.PanelFactory.panel(previewAllJTextField).withLabel("all")).
                createPanel();
        return p;
    }

    @Override
    protected void doOKAction() {
        // 注释文本域
        String comment = commentJTextField.getText();
        if (StringUtils.isNotBlank(comment)){
            nowRequestParamStruct.setComment(StringUtils.trimToEmpty(comment));
        }
        requestParamStruct=nowRequestParamStruct;
        super.doOKAction();
    }

    // 增加 参数的非空校验
    /**
     * 校验输入框非空
     * @param textField
     * @param name
     */
    private void validatorJTextFiled(JTextField textField,String name){
        String message = "The "+name+" is not empty!";

        ComponentValidator componentValidator = new ComponentValidator(project).withValidator(
                new Supplier<ValidationInfo>() {
                    @Override
                    public ValidationInfo get() {
                        String textFieldValue = textField.getText();
                        if (StringUtils.isBlank(textFieldValue)) {
                            getOKAction().setEnabled(false);
                            return new ValidationInfo(message, textField);
                        }else {
                            textFieldValue=StringUtils.trim(textFieldValue);
                            if (MapUtils.isEmpty(requestParamName2StructDataMap)){
                                getOKAction().setEnabled(true);
                            }else if(requestParamName2StructDataMap.containsKey(textFieldValue)){
                                // 是添加
                                if (StringUtils.equalsIgnoreCase(type,"add")){
                                    return new ValidationInfo("The \""+textFieldValue+"\" parameter name already exist !", textField);
                                }else {
                                    if(!requestParamName2StructDataMap.get(textFieldValue).equals(requestParamStruct)){
                                        return new ValidationInfo("The \""+textFieldValue+"\" parameter name already exist !", textField);
                                    }else {
                                        getOKAction().setEnabled(true);
                                    }
                                }
                            }else {
                                getOKAction().setEnabled(true);
                            }
                        }
                        return null;
                    }
                }).installOn(textField);

        componentValidator.updateInfo(new ValidationInfo(message, textField));
        textField.getDocument().addDocumentListener(new DocumentAdapter() {
            @Override
            protected void textChanged(@NotNull DocumentEvent e) {
                ComponentValidator.getInstance(textField).ifPresent(v -> v.revalidate());
            }


        });
    }

    /**
     * 参数搜索列表框响应方法
     * @param searchTextField
     */
    private ComponentPanelBuilder searchParameterTextResponse(SearchTextField searchTextField){

        // 缓存的类名
        PsiShortNamesCache psiShortNamesCache = PsiShortNamesCache.getInstance(project);

        GlobalSearchScope allSearchScope=GlobalSearchScope.allScope(project);

        // 搜索结果列表
        JList searchClassNameJList = new JBList();// 名称的List
        searchClassNameJList.setSelectionModel(new SingleSelectionModel());


        searchTextField.addDocumentListener(new DocumentAdapter() {
            @Override
            protected void textChanged(@NotNull DocumentEvent e) {
                PsiClass[] arraySearchPsiClass = psiShortNamesCache.getClassesByName(searchTextField.getText(), allSearchScope);

                System.out.println("arraySearchPsiClass:"+arraySearchPsiClass);
                if (arraySearchPsiClass!=null&&arraySearchPsiClass.length!=0){
                    Set<String> qualifiedNameList=new TreeSet<>();
                    for (PsiClass psiClass:arraySearchPsiClass){
                        String qualifiedName = psiClass.getQualifiedName();
//                        JvmClassKind classKind = psiClass.getClassKind();
//                        if (classKind.equals(JvmClassKind.ANNOTATION)||classKind.equals(JvmClassKind.INTERFACE)){
//                            continue;
//                        }
                        System.out.println(qualifiedName);

                        qualifiedNameList.add(qualifiedName);
                    }
                    searchClassNameJList.setListData(qualifiedNameList.toArray());
                }
            }
        });

        // 增加列表选中事件
        searchClassNameJList.addListSelectionListener(new ListSelectionListener() {
            @Override
            public void valueChanged(ListSelectionEvent evt) {
                if (!evt.getValueIsAdjusting()) {//This line prevents double events
                    Object selectedValue = searchClassNameJList.getSelectedValue();
                    System.out.println(selectedValue);
                    if (selectedValue==null){
                        return;
                    }
                    String qualifiedName= StringUtils.trim((String) selectedValue);
                    if (StringUtils.isBlank(qualifiedName)){
                        return;
                    }
                    // 包名
                    String packageName=StringUtils.trim(StringUtils.substringBeforeLast(qualifiedName,"."));
                    // 类名
                    String className=StringUtils.trim(StringUtils.substringAfterLast(qualifiedName,"."));

//                    String parameter = StringUtils.trimToEmpty(parameterJTextField.getText());
//
//                    String simpleShowParameter = className + " " + parameter;
//                    String allShowParameter=packageName+"."+simpleShowParameter;

//                    previewAllJTextField.setText(allShowParameter);
//                    previewSimpleJTextField.setText(simpleShowParameter);

                    nowRequestParamStruct.setPackageName(packageName);
                    nowRequestParamStruct.setClassName(className);

                    showData();

                }
            }
        });

        ToolbarDecorator decorator = ToolbarDecorator.createDecorator(searchClassNameJList);
        //禁用列表的增加、删除、移动等功能
        decorator.disableAddAction();
        decorator.disableRemoveAction();
        decorator.disableDownAction();
        decorator.disableUpAction();
        decorator.disableUpDownActions();

//        JBScrollPane pane = new JBScrollPane(decorator.createPanel());
        JPanel pane = decorator.createPanel();
        pane.setPreferredSize(JBUI.size(350, 100));
        pane.putClientProperty(UIUtil.KEEP_BORDER_SIDES, SideBorder.ALL);


        ComponentPanelBuilder componentPanelBuilder = UI.PanelFactory.panel(pane)
                .resizeY(true).resizeX(true);
        return componentPanelBuilder;
    }
    /**
     * 泛型搜索列表框响应方法
     * @param genericsSearchTextField
     */
    private ComponentPanelBuilder genericsSearchParameterTextResponse(SearchTextField genericsSearchTextField,int index){

        // 缓存的类名
        PsiShortNamesCache psiShortNamesCache = PsiShortNamesCache.getInstance(project);

        GlobalSearchScope allSearchScope=GlobalSearchScope.allScope(project);

        // 搜索结果列表
        JList genericsClassNameJList = new JBList();// 名称的List
        genericsClassNameJList.setSelectionModel(new SingleSelectionModel());


        genericsSearchTextField.addDocumentListener(new DocumentAdapter() {
            @Override
            protected void textChanged(@NotNull DocumentEvent e) {
                PsiClass[] arraySearchPsiClass = psiShortNamesCache.getClassesByName(genericsSearchTextField.getText(), allSearchScope);

                System.out.println("arraySearchPsiClass:"+arraySearchPsiClass);
                Set<String> qualifiedNameList=new TreeSet<>();
                qualifiedNameList.add("<clear>");
                if (arraySearchPsiClass!=null&&arraySearchPsiClass.length!=0){
                    for (PsiClass psiClass:arraySearchPsiClass){
                        String qualifiedName = psiClass.getQualifiedName();
//                        JvmClassKind classKind = psiClass.getClassKind();
//                        if (classKind.equals(JvmClassKind.ANNOTATION)||classKind.equals(JvmClassKind.INTERFACE)){
//                            continue;
//                        }
                        System.out.println(qualifiedName);

                        qualifiedNameList.add(qualifiedName);
                    }
                }
                genericsClassNameJList.setListData(qualifiedNameList.toArray());
            }
        });

        // 增加列表选中事件
        genericsClassNameJList.addListSelectionListener(new ListSelectionListener() {
            @Override
            public void valueChanged(ListSelectionEvent evt) {
                if (!evt.getValueIsAdjusting()) {//This line prevents double events
                    Object selectedValue = genericsClassNameJList.getSelectedValue();
                    System.out.println(selectedValue);
                    if (selectedValue==null){
                        return;
                    }
                    String qualifiedName= StringUtils.trim((String) selectedValue);
                    if (StringUtils.isBlank(qualifiedName)){
                        return;
                    }
                    List<ImportStruct> genericsClassStructList = nowRequestParamStruct.getGenericsClassStructList();

                    if (CollectionUtils.isEmpty(genericsClassStructList)){
                        genericsClassStructList=new ArrayList<>();
                        for(int i=0;i<2;i++){
                            ImportStruct importStruct=new ImportStruct();
                            genericsClassStructList.add(importStruct);
                        }
                        nowRequestParamStruct.setGenericsClassStructList(genericsClassStructList);
                    }else if (genericsClassStructList.size()==1){
                        ImportStruct importStruct=new ImportStruct();
                        genericsClassStructList.add(index,importStruct);
                    }
                    // 清空
                    if (StringUtils.equalsIgnoreCase(StringUtils.trim(qualifiedName),"<clear>")){
                        try{
                            ImportStruct importStruct = genericsClassStructList.get(index);
                            importStruct.setClassName(null);
                            importStruct.setPackageName(null);
                            showData();
                            return;
                        }catch (Exception e){
                            e.printStackTrace();
                        }
                    }

                    // 包名
                    String packageName=StringUtils.trim(StringUtils.substringBeforeLast(qualifiedName,"."));
                    // 类名
                    String className=StringUtils.trim(StringUtils.substringAfterLast(qualifiedName,"."));

                    if (CollectionUtils.isEmpty(genericsClassStructList)){
                        genericsClassStructList=new ArrayList<>();
                        ImportStruct genericsClassStruct=new ImportStruct();
                        genericsClassStruct.setPackageName(packageName);
                        genericsClassStruct.setClassName(className);
                        genericsClassStructList.add(genericsClassStruct);
                        nowRequestParamStruct.setGenericsClassStructList(genericsClassStructList);
                    }else if(genericsClassStructList.size()==1){
                        if (index==0){
                            ImportStruct genericsClassStruct=genericsClassStructList.get(0);
                            genericsClassStruct.setPackageName(packageName);
                            genericsClassStruct.setClassName(className);
                        }else{
                            ImportStruct genericsClassStruct=new ImportStruct();
                            genericsClassStruct.setPackageName(packageName);
                            genericsClassStruct.setClassName(className);
                            genericsClassStructList.add(genericsClassStruct);
                        }
                    } else {
                        ImportStruct genericsClassStruct=genericsClassStructList.get(index);
                        genericsClassStruct.setPackageName(packageName);
                        genericsClassStruct.setClassName(className);
                    }

                    // 清空
//                    if (StringUtils.equalsIgnoreCase(StringUtils.trim(qualifiedName),"<clear>")){
//                        genericsClassStructList.remove(index);
//                    }

                    showData();
                }
            }
        });

        ToolbarDecorator decorator = ToolbarDecorator.createDecorator(genericsClassNameJList);
        //禁用列表的增加、删除、移动等功能
        decorator.disableAddAction();
        decorator.disableRemoveAction();
        decorator.disableDownAction();
        decorator.disableUpAction();
        decorator.disableUpDownActions();

//        JBScrollPane pane = new JBScrollPane(decorator.createPanel());
        JPanel pane = decorator.createPanel();
        pane.setPreferredSize(JBUI.size(350, 100));
        pane.putClientProperty(UIUtil.KEEP_BORDER_SIDES, SideBorder.ALL);


        ComponentPanelBuilder componentPanelBuilder = UI.PanelFactory.panel(pane)
                .resizeY(true).resizeX(true);
        return componentPanelBuilder;
    }

    /**
     * 显示数据
     */
    private void showData(){
        String packageName = StringUtils.trimToEmpty(nowRequestParamStruct.getPackageName());
        String className = StringUtils.trimToEmpty(nowRequestParamStruct.getClassName());
        String paramName = StringUtils.trimToEmpty(nowRequestParamStruct.getParamName());


        List<ImportStruct> genericsClassStructList = nowRequestParamStruct.getGenericsClassStructList();
        if (CollectionUtils.isEmpty(genericsClassStructList)){
            if (StringUtils.isBlank(paramName)){
                previewSimpleJTextField.setText(className);
                previewAllJTextField.setText(packageName+"."+className);
            }else {
                previewSimpleJTextField.setText(className+" "+paramName);
                previewAllJTextField.setText(packageName+"."+className+" "+paramName);
            }
        }else {
            StringBuilder simpleSb=new StringBuilder();
            StringBuilder allSb=new StringBuilder();

            if (StringUtils.isNotBlank(className)){
                simpleSb.append(className);
                allSb.append(packageName+"."+className);
            }
            simpleSb.append("<");
            allSb.append("<");

            for(int i=0;i<genericsClassStructList.size();i++){
                ImportStruct importStruct=genericsClassStructList.get(i);
                if (StringUtils.isBlank(importStruct.getClassName())){
                    continue;
                }
                // TODO
//                if (i!=0) {
                if (!StringUtils.endsWith(simpleSb.toString(),"<")) {
                    simpleSb.append(",");
                    allSb.append(",");
                }
                simpleSb.append(importStruct.getClassName());
                allSb.append(importStruct.getPackageName()+"."+importStruct.getClassName());
            }
            simpleSb.append(">");
            allSb.append(">");
            if (StringUtils.isBlank(paramName)){
                previewSimpleJTextField.setText(simpleSb.toString());
                previewAllJTextField.setText(allSb.toString());
            }else {
                previewSimpleJTextField.setText(simpleSb.toString()+" "+paramName);
                previewAllJTextField.setText(allSb.toString()+" "+paramName);
            }
        }
    }

    public RequestParamStruct getRequestParamStruct() {
        return requestParamStruct;
    }

    public void setRequestParamStruct(RequestParamStruct requestParamStruct) {
        this.requestParamStruct = requestParamStruct;
    }
}
